package com.local.goods.controller;

import com.local.common.util.PageResultUtil;
import com.local.common.util.ResultUtil;
import com.local.goods.pojo.*;
import com.local.goods.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品管理控制器
 */
@Slf4j
@Controller
@RequestMapping("/goods")
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    /**
     * rabbitmq操作对象
     */
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${rabbitmq.goods-es-exchange}")
    private String goodsESExchange;

    @Value("${rabbitmq.goods-es-update-routing-key}")
    private String goodsESUpdateRoutingKey;

    @Value("${rabbitmq.goods-es-delete-routing-key}")
    private String goodsESDeleteRoutingKey;


    /**
     * 通过id查询商品
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ResponseBody
    public ResultUtil<Goods> getById(@PathVariable("id") Integer id) {
        if (Objects.isNull(id) || id <= 0) {
            return new ResultUtil(201, "参数错误");
        }
        Goods goods = goodsService.getById(id);
        if (Objects.nonNull(goods)) {
            return new ResultUtil(200, "", goods);
        } else {
            return new ResultUtil(201, "查询失败，请稍后再试");
        }
    }


    /**
     * 查询商品列表，支持翻页（后台管理）
     * @param requestParam
     * @return
     */
    @GetMapping("/list")
    @ResponseBody
    public ResultUtil list(@RequestBody GoodsListRequestParam requestParam) {
        Integer page = requestParam.getPage();
        page = Objects.isNull(page) || page <= 0 ? 1 : page;
        Integer limit = requestParam.getLimit();
        limit = Objects.isNull(limit) || limit <= 0 ? 10 : limit;
        String sort = requestParam.getSort();
        sort = Objects.isNull(sort) || sort.isEmpty() ? "goods_id" : sort;
        String order = requestParam.getOrder();
        order = Objects.isNull(order) || order.isEmpty() ? "desc" : order;
        String goodsName = requestParam.getGoodsName();
        goodsName = Objects.isNull(goodsName) ? "" : goodsName;
        Integer goodsSellStatus = requestParam.getGoodsSellStatus();
        goodsSellStatus = Objects.isNull(goodsSellStatus) || goodsSellStatus < 0 ? -1 : goodsSellStatus;

        PageResultUtil<Goods> goodsList = goodsService.findGoodsList(page, limit, sort, order, goodsName, goodsSellStatus);
        if (Objects.nonNull(goodsList)) {
            return new ResultUtil(200, "", goodsList);
        } else {
            return new ResultUtil(201, "请求失败，请稍后再试");
        }
    }


    /**
     * 新增商品（后台管理）
     * @param goods
     * @return
     */
    @PostMapping("/save")
    @ResponseBody
    public ResultUtil save(@RequestBody Goods goods) {
        Integer saveResult = goodsService.save(goods);
        if (saveResult > 0) {
            //将新增的goods发送给队列，然后同步新增至es搜索的文档
            rabbitTemplate.convertAndSend(this.goodsESExchange, this.goodsESUpdateRoutingKey, goods.getGoodsId().toString());

            return new ResultUtil(200, "添加成功");
        } else {
            return new ResultUtil(201, "添加失败，请稍后再试");
        }
    }


    /**
     * 修改。注意：商品下架的时候，要检查商品是否在首页的推荐栏目中（后台管理）
     * @param goods
     * @return
     */
    @PostMapping("/update")
    @ResponseBody
    public ResultUtil update(@RequestBody Goods goods) {
        Integer updateResult = goodsService.update(goods);
        if (updateResult > 0) {
            //将修改的goods发送给队列，然后同步修改至es搜索的文档
            rabbitTemplate.convertAndSend(this.goodsESExchange, this.goodsESUpdateRoutingKey, goods.getGoodsId().toString());

            return new ResultUtil(200, "修改成功");
        } else {
            return new ResultUtil(201, "修改失败，请稍后再试");
        }
    }


    /**
     * 商品的上架和下架（后台管理）
     * @param requestParam
     * @return
     */
    @PutMapping("/status")
    @ResponseBody
    public ResultUtil status(@RequestBody GoodsStatusRequestParam requestParam) {
        Integer[] ids = requestParam.getIds();
        Integer goodsSellStatus = requestParam.getGoodsSellStatus();
        Integer updateUserId = requestParam.getUpdateUserId();
        String updateTime = requestParam.getUpdateTime();
        Integer updateResult = goodsService.updateStatus(ids, goodsSellStatus, updateUserId, updateTime);
        String message = goodsSellStatus == 0 ? "上架" : "下架";
        if (updateResult > 0) {
            //上下架商品，需要同步修改至es搜索的文档
            String idArrString = Arrays.toString(ids);
            String idString = idArrString.substring(1, idArrString.length() - 1);//1,2,3
            if (goodsSellStatus == 0) {
                //上架，则在es中新增对应的文档
                rabbitTemplate.convertAndSend(this.goodsESExchange, this.goodsESUpdateRoutingKey, idString);
            } else {
                //下架，则在es中删除对应的文档
                rabbitTemplate.convertAndSend(this.goodsESExchange, this.goodsESDeleteRoutingKey, idString);
            }

            return new ResultUtil(200, message + "成功");
        } else {
            return new ResultUtil(201, message + "失败，请稍后再试");
        }
    }


    /**
     * 通过id查询商品，不包括“商品详情”字段
     * @param id
     * @return
     */
    @GetMapping("/simple/{id}")
    @ResponseBody
    public ResultUtil<Goods> getSimpleById(@PathVariable("id") Integer id) {
        if (Objects.isNull(id) || id <= 0) {
            return new ResultUtil(201, "参数错误");
        }
        Goods goods = goodsService.getSimpleById(id);
        if (Objects.nonNull(goods)) {
            return new ResultUtil(200, "", goods);
        } else {
            return new ResultUtil(201, "查询失败，请稍后再试");
        }
    }


    /**
     * 通过ids批量查询商品列表
     * @param ids
     * @return
     */
    @GetMapping("/listByIds")
    @ResponseBody
    public ResultUtil getGoodsListByIds(@RequestBody List<Integer> ids) {
        List<Goods> goodsList = goodsService.getGoodsListByIds(ids);
        if (Objects.nonNull(goodsList)) {
            return new ResultUtil(200, "", goodsList);
        } else {
            return new ResultUtil(201, "请求失败，请稍后再试");
        }
    }


    /**
     * 批量更新商品库存
     * @param goodsStockNumList
     * @return
     */
    @PostMapping("/updateGoodsStockNum")
    @ResponseBody
    public ResultUtil updateGoodsStockNum(@RequestBody List<Goods> goodsStockNumList) {
        return goodsService.updateGoodsStockNum(goodsStockNumList);
    }


    /**
     * 使用elasticsearch，按关键词keywords，对goods进行搜索
     * @param param
     * @return
     */
    @GetMapping("/search")
    @ResponseBody
    public ResultUtil search(@RequestBody GoodsESRequestParam param) {
        PageResultUtil<GoodsESDoc> goodsDocList = goodsService.search(param);
        if (Objects.nonNull(goodsDocList)) {
            return new ResultUtil(200, "", goodsDocList);
        } else {
            return new ResultUtil(201, "搜索失败，请稍后再试");
        }
    }


    /**
     * 初始化es中商品goods文档的数据，将mysql中goods表的数据，同步到es中goods文档
     * @return 文档总数
     */
    @GetMapping("/initSearchDocData/{page}")
    @ResponseBody
    public ResultUtil initSearchDocData(@PathVariable("page") Integer page) {
        Integer result = goodsService.initSearchDocData(page);
        if (result > 0) {
            return new ResultUtil<>(200, "success:"+result, result);
        }else if (result == 0) {
            return new ResultUtil<>(200, "success:"+result, result);
        } else {
            return new ResultUtil<>(201, "failed:"+result, result);
        }
    }


    /**
     * 搜索的自动补齐，即搜索建议
     * @param keywords
     * @return
     */
    @PostMapping("/searchSuggestion")
    @ResponseBody
    public ResultUtil<List<String>> searchSuggestion(@RequestBody String keywords) {
        List<String> suggestionList = goodsService.searchSuggestion(keywords);
        if (Objects.isNull(suggestionList)) {
            return new ResultUtil(201, "请求失败，请稍后再试", null);
        } else {
            return new ResultUtil(200, "请求成功", suggestionList);
        }

    }
}
